﻿//Created by Action Script Viewer - http://www.buraks.com/asv
package net.wooga.pets.models {
    import flash.events.*;
    import flash.display.*;
    import flash.utils.*;
    import __AS3__.vec.*;
    import net.wooga.pets.interfaces.*;
    import org.osflash.signals.*;
    import net.wooga.pets.constants.*;
    import org.robotlegs.mvcs.*;
    import net.wooga.pets.utils.*;

    public class TickModel extends Actor {

        private var _frameTime:Number;
        private var _targetFPS:Number;
        private var _timestamp:Number;
        private var _isPause:Boolean;
        private var _time:Number;
        private var _isFramerateAcceptable:Boolean;
        private var _fpsCount:int;// = 0
        private var _stage:Stage;
        private var _framerateIsNotAcceptableCount:int;// = 0
        private var _qualities:Vector.<String>;
        private var _currentQuality:int = 2
        private var _enforcedQuality:Boolean;// = false
        private var _queues:Dictionary;
        private var _lastTime:Number;// = 0
        private var _factor:Number = 1
        private var _pauseCount:int;// = 0
        private var _currentFPS:int;// = 0

        private static const MIN_QUALITY:int = 1;
        private static const MAX_QUALITY:int = 2;
        private static const MIN_SLOW_FRAMES:int = 5;
        private static const MIN_FPS:int = 20;
        private static const MAX_FPS:int = 28;

        public function TickModel(){
            this._qualities = new Vector.<String>();
            this._queues = new Dictionary();
            super();
            this._qualities.push(StageQuality.LOW, StageQuality.MEDIUM, StageQuality.HIGH, StageQuality.BEST);
        }
        public function reset():void{
            this._queues = new Dictionary();
        }
        public function set stage(_arg1:Stage):void{
            this._stage = _arg1;
        }
        public function get factor():Number{
            return (this._factor);
        }
        public function get currentFPS():int{
            return (this._currentFPS);
        }
        public function start(_arg1:Number):void{
            this._frameTime = (TimeConstants.SECOND / this._stage.frameRate);
            this._time = getTimer();
            this._stage.addEventListener(Event.ENTER_FRAME, this.onEnterFrame);
        }
        private function onEnterFrame(_arg1:Event):void{
            this._fpsCount++;
            this.handleTick();
        }
        public function get targetFPS():Number{
            return (this._targetFPS);
        }
        public function set targetFPS(_arg1:Number):void{
            this._targetFPS = _arg1;
        }
        public function set timestamp(_arg1:Number):void{
            this._timestamp = _arg1;
        }
        public function get timestamp():Number{
            return (this._timestamp);
        }
        public function registerTicking(_arg1:ITicking, _arg2:int, _arg3:Boolean):void{
            this._queues[_arg2] = ((this._queues[_arg2]) || (new Signal(Boolean, Number)));
            var _local4:Signal = (this._queues[_arg2] as Signal);
            _local4.add(_arg1.onTick);
            if (((!(this._isPause)) && (_arg3))){
                _arg1.onTick(true, this._timestamp);
            };
        }
        public function unregisterTicking(_arg1:ITicking):void{
            var _local2:Signal;
            for each (_local2 in this._queues) {
                _local2.remove(_arg1.onTick);
            };
        }
        public function get pause():Boolean{
            return (this._isPause);
        }
        public function set pause(_arg1:Boolean):void{
            this._pauseCount = (this._pauseCount + (_arg1) ? 1 : -1);
            this._pauseCount = Numbers.constrain(this._pauseCount, 0, Number.MAX_VALUE);
            this._isPause = (this._pauseCount > 0);
            var _local2:String = (this._isPause) ? EventConstants.TICK_PAUSED : EventConstants.TICK_STARTED;
            dispatch(new Event(_local2));
        }
        private function handleTick():void{
            var _local1:Number = getTimer();
            this._lastTime = ((this._lastTime) || ((_local1 - this._frameTime)));
            this._factor = ((_local1 - this._lastTime) / this._frameTime);
            this.handleFPS(_local1);
            if (!this._isPause){
                this.checkQueuesForTicks(_local1);
            };
            this._lastTime = _local1;
        }
        private function handleFPS(_arg1:Number):void{
            var _local3:Number;
            var _local2:Number = (_arg1 - this._time);
            if (_local2 >= TimeConstants.SECOND){
                this._timestamp++;
                _local3 = (_local2 - 1000);
                this._time = (_arg1 - _local3);
                this._isFramerateAcceptable = (this._fpsCount >= MIN_FPS);
                if (!this._isFramerateAcceptable){
                    if (this._framerateIsNotAcceptableCount >= MIN_SLOW_FRAMES){
                        this.adjustQuality(-1, false);
                    };
                    this._framerateIsNotAcceptableCount++;
                } else {
                    if (this._fpsCount > MAX_FPS){
                        this.adjustQuality(1, false);
                        this._framerateIsNotAcceptableCount = 0;
                    };
                };
                this._currentFPS = this._fpsCount;
                this._fpsCount = 0;
            };
        }
        public function adjustQuality(_arg1:int, _arg2:Boolean=true):void{
            var _local3:int;
            var _local4:String;
            if (((!(this._enforcedQuality)) || (_arg2))){
                this._enforcedQuality = _arg2;
                _local3 = (this._currentQuality + _arg1);
                this._currentQuality = ((_arg1)<0) ? Math.max(MIN_QUALITY, _local3) : Math.min(MAX_QUALITY, _local3);
                _local4 = this._qualities[this._currentQuality];
                if (((_local4) && (!((_local4.toUpperCase() == this._stage.quality))))){
                    this._stage.quality = _local4;
                };
            };
        }
        public function releaseQualityEnforcement():void{
            this._enforcedQuality = false;
        }
        private function checkQueuesForTicks(_arg1:Number):void{
            var _local2:int;
            var _local3:Signal;
            var _local4:String;
            for (_local4 in this._queues) {
                _local2 = int(_local4);
                if (this.isTickingNow(_local2, _arg1)){
                    _local3 = (this._queues[_local2] as Signal);
                    _local3.dispatch(this._isFramerateAcceptable, this._timestamp);
                };
            };
            this._lastTime = _arg1;
        }
        private function isTickingNow(_arg1:int, _arg2:Number):Boolean{
            var _local3:int;
            var _local4:int;
            if (_arg1 == 0){
                return (true);
            };
            _local3 = int((this._lastTime / _arg1));
            _local4 = int((_arg2 / _arg1));
            return ((_local4 > _local3));
        }

    }
}//package net.wooga.pets.models 
